package com.yourcompany.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yourcompany.api.dto.ChargingOrderCreateDTO;
import com.yourcompany.api.dto.OrderQueryDTO;
import com.yourcompany.api.entity.ChargingOrder;
import com.yourcompany.api.entity.Order;
import com.yourcompany.api.enums.ChargingOrderStatusEnum;
import com.yourcompany.api.mapper.ChargingOrderMapper;
import com.yourcompany.api.service.ChargingOrderService;
import com.yourcompany.api.service.OrderService;
import com.yourcompany.api.strategy.PaymentStrategy;
import com.yourcompany.api.vo.PaymentVO;
import com.yourcompany.common.enums.OrderStatusEnum;
import com.yourcompany.common.exception.BusinessException;
import com.yourcompany.common.enums.OrderTypeEnum;
import com.yourcompany.service.factory.PaymentStrategyFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

@Service
public class ChargingOrderServiceImpl extends ServiceImpl<ChargingOrderMapper, ChargingOrder> implements ChargingOrderService {

    @Autowired
    private PaymentStrategyFactory paymentStrategyFactory;

    @Autowired
    private OrderService orderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChargingOrder createChargingOrder(ChargingOrderCreateDTO createDTO) {
        // 参数校验
        if (createDTO.getUserId() == null) {
            throw new BusinessException("用户ID不能为空");
        }
        if (createDTO.getStationId() == null) {
            throw new BusinessException("充电站ID不能为空");
        }
        if (createDTO.getGunId() == null) {
            throw new BusinessException("充电枪ID不能为空");
        }
        if (createDTO.getAmount() == null || createDTO.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("充电金额必须大于0");
        }
        
        // 创建充电订单
        ChargingOrder chargingOrder = new ChargingOrder();
        BeanUtils.copyProperties(createDTO, chargingOrder);
        
        // 设置订单基本信息
        chargingOrder.setOrderNo(generateOrderNo());
        chargingOrder.setStatus(ChargingOrderStatusEnum.UNPAID.getCode());
        chargingOrder.setCreateTime(LocalDateTime.now());
        chargingOrder.setDeleted(0);
        chargingOrder.setAmount(createDTO.getAmount());
        
        // 保存充电订单
        save(chargingOrder);
        
        // 创建支付订单
        Order order = new Order();
        order.setUserId(createDTO.getUserId());
        order.setOrderNo(generateOrderNo());
        order.setOrderType(OrderTypeEnum.CHARGING.getCode());
        order.setBusinessId(chargingOrder.getId());
        order.setAmount(createDTO.getAmount());
        order.setStatus(OrderStatusEnum.UNPAID.getCode());
        order.setPayMethod(createDTO.getPaymentMethod());
        order.setRemark(createDTO.getRemark());
        orderService.save(order);
        
        // 更新充电订单的支付订单ID
        chargingOrder.setPayOrderId(order.getId());
        updateById(chargingOrder);
        
        return chargingOrder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlePaySuccess(Long orderId) {
        // 获取支付订单
        Order order = orderService.getById(orderId);
        if (order == null || !OrderTypeEnum.CHARGING.getCode().equals(order.getOrderType())) {
            throw new BusinessException("订单不存在或类型错误");
        }
        
        // 更新充电订单状态
        ChargingOrder chargingOrder = getById(order.getBusinessId());
        if (chargingOrder == null) {
            throw new BusinessException("充电订单不存在");
        }
        
        chargingOrder.setStatus(ChargingOrderStatusEnum.PAID.getCode());
        updateById(chargingOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startCharging(String orderNo) {
        ChargingOrder order = getByOrderNo(orderNo);
        if (order.getStatus() != 0) {
            throw new BusinessException("订单状态不正确");
        }
        
        order.setStatus(1);
        order.setStartTime(LocalDateTime.now());
        updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endCharging(String orderNo) {
        ChargingOrder order = getByOrderNo(orderNo);
        if (order.getStatus() != 1) {
            throw new BusinessException("订单状态不正确");
        }
        
        order.setStatus(2);
        order.setEndTime(LocalDateTime.now());
        // 计算充电时长和费用
        calculateOrderAmount(order);
        updateById(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(String orderNo) {
        ChargingOrder order = getByOrderNo(orderNo);
        if (order.getStatus() != 0) {
            throw new BusinessException("订单状态不正确");
        }
        
        order.setStatus(3);
        updateById(order);
    }

    @Override
    public PaymentVO payOrder(String orderNo, String paymentMethod) {
        ChargingOrder order = getByOrderNo(orderNo);
        if (order.getStatus() != 2) {
            throw new BusinessException("订单状态不正确");
        }
        
        PaymentStrategy strategy = paymentStrategyFactory.getStrategy(paymentMethod);
        return strategy.createPayment(orderNo, order.getTotalAmount().toString());
    }

    @Override
    public boolean queryPayment(String orderNo) {
        ChargingOrder order = getByOrderNo(orderNo);
        PaymentStrategy strategy = paymentStrategyFactory.getStrategy(order.getPaymentMethod());
        return strategy.queryPayment(orderNo);
    }

    @Override
    public IPage<ChargingOrder> pageOrders(IPage<ChargingOrder> page, OrderQueryDTO queryDTO) {
        LambdaQueryWrapper<ChargingOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(queryDTO.getOrderNo()), ChargingOrder::getOrderNo, queryDTO.getOrderNo())
                .eq(queryDTO.getUserId() != null, ChargingOrder::getUserId, queryDTO.getUserId())
                .eq(queryDTO.getStationId() != null, ChargingOrder::getStationId, queryDTO.getStationId())
                .eq(queryDTO.getStatus() != null, ChargingOrder::getStatus, queryDTO.getStatus())
                .ge(StringUtils.isNotBlank(queryDTO.getStartTime()), ChargingOrder::getCreateTime, queryDTO.getStartTime())
                .le(StringUtils.isNotBlank(queryDTO.getEndTime()), ChargingOrder::getCreateTime, queryDTO.getEndTime())
                .orderByDesc(ChargingOrder::getCreateTime);
        return page(page, wrapper);
    }

    /**
     * 根据订单号查询充电订单信息。
     *
     * 该方法通过订单号从数据库中查询对应的充电订单。如果查询结果为空，则抛出业务异常，提示订单不存在。
     *
     * @param orderNo 订单号，用于查询对应的充电订单。
     * @return 返回查询到的充电订单对象。
     * @throws BusinessException 如果订单不存在，则抛出此异常。
     */
    private ChargingOrder getByOrderNo(String orderNo) {
        // 使用lambdaQuery方法查询订单，根据订单号进行匹配
        ChargingOrder order = lambdaQuery()
                .eq(ChargingOrder::getOrderNo, orderNo)
                .one();

        // 如果查询结果为空，抛出业务异常
        if (order == null) {
            throw new BusinessException("订单不存在");
        }

        // 返回查询到的订单对象
        return order;
    }
    
    /**
     * 生成订单号
     * 格式：CG + 年月日时分秒 + 6位随机数
     */
    private String generateOrderNo() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.format("%06d", new Random().nextInt(1000000));
        return "CG" + timestamp + random;
    }
    
    private void calculateOrderAmount(ChargingOrder order) {
        // 实现费用计算逻辑
    }
} 